微服务架构谈(6):从监控到故障定位
六、服务调用跟踪
众所周知,trace架构基本都源自Google Dapper。
下图为高德在基于trace基础上做的场景应用,比如服务状态自我诊断、监控追溯等。
上图为支付宝app通过无线网关的trace示意图,包括应用链路,文件存储。应用链路包括rpc调用和消息服务。《分布式服务框架》一书,林峰特别对服务调用链价值进行了汇总,体现了对于不同角色,服务调用链路跟踪的价值所在。
开发:
架构优化
消除不合理依赖
性能优化
还可以补充容量评测、设计变更分析等
测试:
识别调用流程
优化测试用例
关键路径覆盖率
还可以补充自动化端到端测试
运维:
故障定界
故障定位
提前预警
易故障点识别
七、不能承受之重:监控
7.1 监控预警的疑难问题
监控最大的问题是消息很多,我来不及看。漏报伤不起,误报也很烦,说不想半夜三更好好的睡睡觉。总结监控预警的疑难问题,大致可以分为几类:
报警多到没朋友、长期容易懈怠
不容易觉察的阴跌或者缓慢性问题
周期性波动导致的误报或漏报
报警多到没朋友、长期容易懈怠
对于固定阈值的报警,没有可调适性,可以形成动态阈值方案,在动态阈值上限、下限范围内都属于业务正常。
不容易察觉的阴跌或者缓慢性问题
Service耗时在不断的增加,一直到濒临临界点爆发。采取常规固定阈值或者同环比的监控,比较难发现问题。
对于上图,绿色线为观测时间,通过变点检测方法,相比传统阈值报警发现时间可以做一定的提前。
周期性波动导致的误报或漏报
周日和工作时间的业务规模,用户影响业务模型有差别,亦可通过动态阈值方案来尽量减少误报,规避漏报。周期性可以分为几种:按日、按周、按月、按工作日等方式,需要针对不同业务定义不同的预警方式。通过多次优化可以总结出如下预警阈值的优化方法:
分类法:把业务按业务波动分类:定时任务类业务、平稳类业务,针对不同业务配置的阈值及取值方式不对。例如:外部商户交易是平稳业务性的,业务曲线相对平稳,取值方式可以环比和同比结合起来使用配置,而XX代扣、XX代发业务都是波动性业务,对应监控阈值除了同比还需要考虑业务量范围。
业务波动学习法:经过分析部分业务在固定时间点会有波动,可以考虑针对业务分段监控,在波动段采用环比+值范围的监控方式。例如:XX交易每天在10点、20点、0点都是有比较大的波动,其他整点时间有小量波动。
时间分段法:针对现有业务变更一般都是在白天发生,同时晚上有一些业务存在定时和由于量小导致的波动曲线大的问题,可以考针对09:00至21:00和21:00至09:00配置不同阈值。
因此,配置监控预警阈值会在预警准确性和去噪音两者之间取舍,人工配置预警的方式永远找不到银弹,未来还是需要考虑通过智能化的方式去学习业务波动渠道才是最终解决方案。
7.2 智能定位问题
在大型SOA架构的系统中,包括采用了微服务设计的一系列服务中,定位RootCause是一个老大难问题。交易下跌了,是支付的问题,还是营销的问题?是应用系统问题还是数据库切换到读库状态了?在传统的运维模式中基本靠”喊”。大盘出问题了,大家都看一下自己的系统!然后人肉综合判断。为了更好的做RootCause的定位,需要一套支撑根因分析与定位的系统。目前流行的有基于知识经验的定位、基于有监督算法的定位这2类。
基于知识经验的定位
顾名思义,基于知识经验的定位是把人肉经验固化的一种方法。特点是见效快,特别是历史出过的问题,而且可以举一反三,分门别类。确定是检测代码的维护问题,随着系统变更,调用链路和依赖存储的变化,检测代码需要做同步变更。另外,此方案对于发现完全陌生类型的问题,收效存疑。
如上图所示,其实质是关联指标法。比如,发现点击率下降,可以从人工经验总结的影响ctr波动的系统内部(模型、算法、索引、数据等)指标入手,依次检测是否正常。此类方法,可以描述成一棵可追溯的树,层次深入。
基于有监督算法的定位
系统风险的发现和定位属于异常检测(Anomaly Detection)的范畴,在该领域通常有监督模型法(SupervisedModel)、聚类模型法(Unsupervised Model)、近邻法(Nearest Neighbor)、统计法(Statistical)、信息论(Information Theory)和谱理论(Spectral Theory)等。一般来说,标注数据的获取是一大难题,所以半监督、无监督的算法在这类场景中大量使用,而我们利用故障注入得到种子标注数据,再通过对种子问题做同类扩展,得到大量标注样本,然后基于样本构建分类模型,预测每次系统调用的风险,对有问题的调用进行报警,并结合调用参数、系统变更数据对根因进行定位。我们将智能定位问题分为两步实现:1、检测问题;2、定位问题。这里展开一下检测问题,定位问题的解法后面专文叙述。
评估智能检测系统的发现问题的效果一般采用“系统风险覆盖率和误报率”。因为缺乏标注数据,这两个指标一直是很难度量的,我们利用故障注入平台的能力设计了有监督综合模型将其分解为4个阶段来实现定量评估:1、历史故障;2、同类延伸历史故障;3、覆盖用例库可能出现的故障及其延伸;4、有创造性的智能延伸故障。整体上,业务通过接入故障注入平台和精细化故障检测平台,使业务具备常态化进攻和防守的“左右互搏”的能力,常态化、周期性拿到系统在风险敞口的指标,辅助或在一些场景帮助业务作出最优决策。
上图描述了攻防结合的反馈与优化闭环,精细化智能检测平台作为防守方,涉及故障延伸方法的设计、有监督综合模型的设计、周期性演练效果的计算三个重要步骤,下面我以某故障为实例来具体说明:
某故障由于业务规则配置出错,引起业务量下降导致,从数据上看,表现为返回参数与正常请求相比有明显缺失,比如:
参数维度1 | 参数维度2 | 参数维度3 | |
正常系统调用 | abc | def | [zzz,yyy, ...] (省略) |
异常系统调用 | abc | def | [] |
显然,异常系统调用在参数维度3上有所体现。通过故障注入,我们便可以拿到历史故障数据,但是如果仅仅使用这些样本进行训练,检测系统也只能覆盖历史出现过的故障,极大的限制了系统的检测范围,所以我们将历史故障数据作为种子,在上面进行同类故障问题数据的扩展。
通过同类故障扩展,模型可以拥有覆盖一类问题的能力,扩大了故障覆盖范围,也更能符合真实的情况。后续我们也尝试基于遗传算法的创造式故障样本扩展,更全面的覆盖风险敞口。
基于拓展样本,我们构建了一个基于有监督算法的综合模型,对异常系统调用进行预测,同时结合特征重要性和实时参数来推理可能引起问题的参数,输出给定位模块。
八、故障注入与常态化演练
8.1 Chaos Principle
Netflix曾发布过Chaos Principle,来阐述chaos工程师的相关工作。Chaos Principle包含4个原则:
Build aHypothesis around Steady State Behavior
Vary Real-worldEvents
Run Experimentsin Production
AutomateExperiments to Run Continuously
Build a Hypothesis around Steady State Behavior:把系统当成黑盒,chaos专注在系统does work,而不是尽量验证它如何工作。 例如当故障或某一个状态发生到恢复期间,系统的吞吐量,错误率,延时分布等。
Chaos Monkey是最受关注的一个产品,顾名思义就是用来捣乱的,怎么捣乱?
把某些运算设备定制掉;把系统延迟时间调长等等。Chaos系列还可以模拟单机房故障。Chaos Monkey 最新版本依赖于Spinnaker这个持续发布平台。
Vary Real-world Events:实际创造真实环境的事件,比如硬件fail,软件不可用来观察演练。
Run Experiments in Production:系统的行为取决于环境和通讯模式,采样真正的流量是唯一的方法来可靠地捕获请求路径。为了保证系统运行的真实性和当前部署的系统的相关性的真实性,chaos喜欢直接在生产流量实验。
Automate Experiments to Run Continuously:chaos工程师通过手工的故障演练不可持续,因此构建自动化演练的机制。
8.2 故障注入
结合chaos principle不难得到结论,由于分布式系统把fail作为”常态”对待,不能等到出现问题采取解决它,应该通过练兵的方式做演习,而演习的目标要做到尽量可重复、安全、接近真实。
故障注入的方式之一通过服务路由来想办法,比如通过Filter模式对于路由进行处理。下图简单示意了通过隔离服务路由,导入测试流量到演练机的一般方法。
如上图所示,系统A>B>C,系统A调用B,B调用C。假设选定对应集群中A Monkey、B Monkey、C Monkey为测试机,则测试流量进入的时候通过服务路由中设置路由到正确的测试机;而正常流量会按照常规配置的路由策略路由到比如A-1-30.xxzone等其他机器中。
目前笔者所见的注入故障分类大致覆盖调用/负载变化、单机服务器故障(比如磁盘、cpu full、内存full等)、下游故障(DB响应变慢、下游返回失败结果等)。
8.3 常态化演练
分布式系统有一个不成文的原则,就是面向fail设计。任何系统、任何资源都可能不可用,要考虑不可用的异常发生时,对应的解决方案。比如ebay的架构原则就有一条,Remember Everything Fails。
在大型互联网站点的架构师心中都形成了一些共识,比如Remember Everything Fails、AutomateEverything。如何做到呢?我们可以把Remember Everything Fails分为三个阶段:
面向Everything Fails设计
验证Everything Fails时的系统表现是否符合预期
常态化、自动化验证(演练)
常态化演练的基本动作包括演练计划、执行场景case注入、观测、故障止血、总结改进等。常态化也包括一些突袭演练,采用红蓝军攻防对抗模式,不仅仅模拟系统表现、也是对整体的应急响应处置流程包括组织流程的检验。
总结:分布式服务化,服务和存储拆分都还算容易,但会对基础设施和技能有更高的要求。如林昊所说,能不服务化的尽量不服务化;无数前辈也告诫过,能不用分布式事务的尽量不用。一入江湖,不得回头。随着业务规模化的发展,在服务治理上需要下的功夫愈走向精细化。
声明:
本文部分插图引用网络公开资料,包括高德稳定性架构实践(雷娃)、支付宝无线-从前端到后端的服务治理 以及 阿里妈妈全景业务监控平台Goldeneye。
……
关注本公众号,欢迎订阅。
技术琐话
以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。本号由坐馆老司机技术团队维护。